import React, {useEffect, useRef} from 'react';
import ReactDOM from 'react-dom';
import G6 from '@antv/g6';
import data from './data.js'

const FlowDiagram = () => {
  const ref = useRef(null);
  useEffect(() => {
    init();
  }, [])

  // useEffect(() => {
  //     window.addEventListener('resize', init());
  //     return () => {
  //         window.removeEventListener('resize', init());
  //     }
  // }, []);

  const init = () => {
    const container = ReactDOM.findDOMNode(ref.current);
    const width = container.scrollWidth * 0.8;
    const height = container.scrollHeight || 500;
    const graph = new G6.TreeGraph({
      container,
      width,
      height,
      fitView: true,
      modes: {
        default: [
          {
            type: 'collapse-expand',
            onChange: function onChange(item, collapsed) {
              const data = item.get('model');
              data.collapsed = collapsed;
              return true;
            },
          },
          'drag-canvas',
          'zoom-canvas',
          'activate-node',
          'running'
        ],
      },
      defaultNode: {
        size: 26,
        anchorPoints: [
          [0, 0.5],
          [1, 0.5],
        ],
        style: {
          fill: '#a3c1fc',
          stroke: '#5B8FF9',
        },
        labelCfg: {
          style: {
            fill: '#fff',
            fontSize: 14,
          },
        },
      },
      defaultEdge: {
        type: 'circle-running',
        style: {
          lineWidth: 2,
          stroke: 'blue',
        },
        labelCfg: {
          position: 'center', // 其实默认就是 center，这里写出来便于理解
          autoRotate: true,   // 使文本随边旋转
          style: {
            stroke: 'white',  // 给文本添加白边和白色背景
            fill: '#a3c1fc',  // 文本颜色
          }
        }
      },
      layout: {
        type: 'mindmap',
        direction: 'H',
        getHeight: () => {
          return 16;
        },
        getWidth: () => {
          return 16;
        },
        getVGap: () => {
          return 10;
        },
        getHGap: () => {
          return 50;
        },
        getSide: (d) => {
          if (d.id === 'Api-Gateway') {
            return 'right';
          }
          return 'left';
        },
      },
      // 节点不同状态下的样式集合
      nodeStateStyles: {
        // 鼠标 hover 上节点，即 hover 状态为 true 时的样式
        hover: {
          fill: 'lightsteelblue',
        },
        // 鼠标点击节点，即 click 状态为 true 时的样式
        click: {
          stroke: '#faad14',
          lineWidth: 5,
        },
      },
      // 边不同状态下的样式集合
      edgeStateStyles: {
        // 鼠标点击边，即 click 状态为 true 时的样式
        click: {
          stroke: 'steelblue',
        },
      },
      animate: true, // Boolean，切换布局时是否使用动画过度，默认为 false
      animateCfg: {
        duration: 500, // Number，一次动画的时长
        easing: 'linearEasing', // String，动画函数
      },
    });

    // const lineDash = [4, 2, 1, 2];
    G6.registerEdge(
      'circle-running',
      {
        afterDraw(cfg, group) {
          // get the first shape in the group, it is the edge's path here=
          const shape = group.get('children')[0];
          // the start position of the edge's path
          const startPoint = shape.getPoint(0);
    
          // add red circle shape
          const circle = group.addShape('circle', {
            attrs: {
              x: startPoint.x,
              y: startPoint.y,
              fill: '#1890ff',
              r: 3,
            },
            name: 'circle-shape',
          });
    
          // animation for the red circle
          circle.animate(
            (ratio) => {
              // the operations in each frame. Ratio ranges from 0 to 1 indicating the prograss of the animation. Returns the modified configurations
              // get the position on the edge according to the ratio
              const tmpPoint = shape.getPoint(ratio);
              // returns the modified configurations here, x and y here
              return {
                x: tmpPoint.x,
                y: tmpPoint.y,
              };
            },
            {
              repeat: true, // Whether executes the animation repeatly
              duration: 3000, // the duration for executing once
            },
          );
        },
      },
      'cubic', // extend the built-in edge 'cubic'
    );

    // let i = 0;
    // graph.edge(function () {
    //   i++;
    //   return {
    //     type: 'cubic-horizontal',
    //     color: '#FFFFFF',
    //     label: i,
    //   };
    // });

    // graph?.clear();
    // graph?.destroy();
    graph.data(data);
    graph.render();
    graph.setItemState('nginx', 'selected', true);
    
    // 监听鼠标进入节点
    graph.on('node:mouseenter', (e) => {
      const nodeItem = e.item;
      const edges = nodeItem.getEdges();
      // 设置目标节点的 hover 状态 为 true
      graph.setItemState(nodeItem, 'hover', true);
      edges.forEach((edge) => graph.setItemState(edge, 'running', true));
    });
    // 监听鼠标离开节点
    graph.on('node:mouseleave', (e) => {
      const nodeItem = e.item;
      const edges = nodeItem.getEdges();
      // 设置目标节点的 hover 状态 false
      graph.setItemState(nodeItem, 'hover', false);
      edges.forEach((edge) => graph.setItemState(edge, 'running', false));
    });
    // 监听鼠标点击节点
    graph.on('node:click', (e) => {
      // 先将所有当前有 click 状态的节点的 click 状态置为 false
      const clickNodes = graph.findAllByState('node', 'click');
      clickNodes.forEach((cn) => {
        graph.setItemState(cn, 'click', false);
      });
      const nodeItem = e.item;
      // 设置目标节点的 click 状态 为 true
      graph.setItemState(nodeItem, 'click', true);
    });
    // 监听鼠标点击节点
    graph.on('edge:click', (e) => {
      // 先将所有当前有 click 状态的边的 click 状态置为 false
      const clickEdges = graph.findAllByState('edge', 'click');
      clickEdges.forEach((ce) => {
        graph.setItemState(ce, 'click', false);
      });
      const edgeItem = e.item;
      // 设置目标边的 click 状态 为 true
      graph.setItemState(edgeItem, 'click', true);
    });

    if (typeof window !== 'undefined') {
      window.onresize = () => {
        if (!graph || graph.get('destroyed')) return;
        if (!container || !container.scrollWidth || !container.scrollHeight) return;
        graph.changeSize(container.scrollWidth, container.scrollHeight);
      };
    }
  }

  return <div className='flowDiagramWarp' style={{background: '#1A1A25'}} ref={ref}></div>;
}

export default FlowDiagram;
